Skip to content

git worktree: add adopt command for existing git worktrees - #9943

Open
calebdw wants to merge 1 commit into
calebdw/push-trvorlkwymykfrom
calebdw/push-szrsklqtlxzq
Open

git worktree: add adopt command for existing git worktrees#9943
calebdw wants to merge 1 commit into
calebdw/push-trvorlkwymykfrom
calebdw/push-szrsklqtlxzq

Conversation

@calebdw

@calebdw calebdw commented Aug 7, 2026

Copy link
Copy Markdown
Member

Add jj git worktree adopt command that adopts existing Git worktrees
as jj workspaces. Three modes are supported:

  • No arguments: adopts the Git worktree at the current directory.
  • Named worktrees: jj git worktree adopt <name>... adopts specific
    Git worktrees by name from any jj workspace or git worktree.
  • --all: adopts all unadopted Git worktrees at once.

The command works from within an existing jj workspace or from inside
an unadopted git worktree by discovering the parent jj repo via git.
Guardrails prevent adopting from the main workspace directory and
report clear errors for already-adopted or nonexistent worktrees.

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, demos/)
  • I have updated the config schema (cli/src/config-schema.json)
  • I have added/updated tests to cover my changes
  • I fully understand the code that I am submitting (what it does,
    how it works, how it's organized), including any code drafted by an LLM.
  • For any prose generated by an LLM, I have proof-read and copy-edited with
    an eye towards deleting anything that is irrelevant, clarifying anything
    that is confusing, and adding details that are relevant. This includes,
    for example, commit descriptions, PR descriptions, and code comments.

@calebdw
calebdw requested a review from a team as a code owner August 7, 2026 21:24
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch 3 times, most recently from dc3e4e4 to 4ed7616 Compare August 7, 2026 22:55
@yuja

yuja commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

This looks quite messy. Can we instead add a maintenance command to enable/disable Git worktree?

@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from 4ed7616 to eb478b3 Compare August 9, 2026 18:32
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from eb478b3 to dc99e45 Compare August 9, 2026 18:38
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch 2 times, most recently from 9564cd7 to fe10f40 Compare August 9, 2026 19:01
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from fe10f40 to f177bca Compare August 9, 2026 19:09
@calebdw

calebdw commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@yuja,

I've pushed updates that clean up the implementation and tried to make it less messy.

On the design question: this behavior only applies to colocated repositories. The whole point of colocation is that jj and git share the same working state---if a user has opted into colocation, then git worktrees are part of that shared state. When another process modifies git refs, HEAD, or the working copy outside of jj, the next jj command automatically imports those changes without requiring a maintenance command. I was trying to extend that same principle to worktrees, which are just another dimension of git state.

This is particularly relevant with AI coding tools (like Claude Code, Cursor, etc.), which increasingly use git worktree add/remove/move to manage parallel sessions. When one of those tools creates a git worktree and then runs jj inside it, it should just work: the same way running jj after git checkout just works today.

I'm not sure how a maintenance command would handle all the different cases that come up:

  • Adopting externally-created worktrees: If someone runs git worktree add ../feature and then cd ../feature && jj status, a maintenance command means that first jj invocation fails instead of working.
  • Forgetting removed worktrees: If an external tool runs git worktree remove, the jj workspace metadata becomes stale. This seems like it should be reconciled automatically, similar to how stale git refs are cleaned up during import.
  • Repairing moved worktrees: git worktree move changes paths that jj tracks. This also feels like state that should be reconciled on the next operation.

Happy to discuss further if you have a specific design in mind.

@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from f177bca to ad95e0b Compare August 9, 2026 19:27
@yuja

yuja commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

When one of those tools creates a git worktree and then runs jj inside it, it should just work: the same way running jj after git checkout just works today.

Maybe I don't follow, but since a jj workspace isn't initialized yet, I don't expect jj would work in that Git worktree directory. It's different from running git checkout in an existing jj workspace.

I don't have a strong feeling about removed worktrees, but it isn't probably a new problem? A jj workspace can also be removed by rm -Rf.

@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch 3 times, most recently from fbade4b to 837ef54 Compare August 10, 2026 13:25
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from 837ef54 to 70e65d2 Compare August 10, 2026 13:52
@PhilipMetzger

Copy link
Copy Markdown
Contributor

I agree with Yuya that this is to messy and see my other comment down in the stack.

@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from 70e65d2 to d376469 Compare August 10, 2026 14:46
@calebdw

calebdw commented Aug 10, 2026

Copy link
Copy Markdown
Member Author

@yuja,

On auto-adopting worktrees: The whole premise of colocation is that jj and git share state, and jj automatically syncs that state on every invocation. When an external tool runs git checkout or modifies refs, jj imports those changes automatically---no maintenance command needed. Git worktrees are just another dimension of that shared git state. If an external tool (which knows nothing about jj) runs git worktree add ../feature, the resulting directory already points back to the same git repo that jj is colocated with. Requiring the user to then run something like jj workspace add --adopt is an unnecessary extra step when we have all the information needed to initialize the workspace automatically. This is especially relevant for AI coding tools that use git worktree add/remove to manage parallel sessions.

On reconciling removed worktrees: This actually is different from rm -Rf. When you rm -Rf a workspace directory, jj still tracks the workspace---it shows up in jj workspace list and jj log as secondary@ with a stale commit. The workspace metadata is orphaned. The same thing happens when an external tool runs git worktree remove. In a colocated repo, if the git worktree is gone, the corresponding jj workspace should be cleaned up too, otherwise you accumulate stale workspace references that the user has to manually forget.

@yuja

yuja commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

As far as I can tell, colocation is a per-workspace state. Users can freely choose to add a non-colocated jj workspace or Git worktree.

I'm not against adding an opt-in feature to synchronize Git worktrees and jj workspaces automatically (similar to snapshot.auto-update-stale), but an explicit command should come first.

@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from d376469 to db4ab64 Compare August 11, 2026 13:38
Comment thread cli/src/commands/workspace/sync.rs Outdated
@calebdw
calebdw marked this pull request as draft August 11, 2026 18:28
Comment thread cli/src/config/misc.toml Outdated
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from 5ec873f to 44c9932 Compare August 11, 2026 18:43
@calebdw calebdw changed the title workspaces: adopt external git worktrees workspace add: support --adopt flag for git worktrees Aug 11, 2026
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch 3 times, most recently from fd76582 to ab4689f Compare August 11, 2026 20:19
@calebdw

calebdw commented Aug 11, 2026

Copy link
Copy Markdown
Member Author

@yuja, @PhilipMetzger I've restructured the PRs 👍

@calebdw
calebdw marked this pull request as ready for review August 11, 2026 20:20
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from ab4689f to e17be61 Compare August 12, 2026 19:40
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from e17be61 to b851f05 Compare August 12, 2026 20:00
@yuja

yuja commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Same here. Something like jj git workspace adapt seems better.

@calebdw
calebdw changed the base branch from calebdw/push-knxntmowqsrr to calebdw/push-trvorlkwymyk August 13, 2026 16:39
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from b851f05 to 3412dc4 Compare August 13, 2026 16:40
@calebdw calebdw changed the title workspace add: support --adopt flag for git worktrees git worktree: add adopt command for existing git worktrees Aug 13, 2026
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch 2 times, most recently from 10ac4ef to ab11256 Compare August 13, 2026 17:24
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch 2 times, most recently from 9f4313d to e8cd42f Compare August 13, 2026 18:13
Add `jj git worktree adopt` command that adopts existing Git worktrees
as jj workspaces. Three modes are supported:

* No arguments: adopts the Git worktree at the current directory.
* Named worktrees: `jj git worktree adopt <name>...` adopts specific
  Git worktrees by name from any jj workspace or git worktree.
* `--all`: adopts all unadopted Git worktrees at once.

The command works from within an existing jj workspace or from inside
an unadopted git worktree by discovering the parent jj repo via git.
Guardrails prevent adopting from the main workspace directory and
report clear errors for already-adopted or nonexistent worktrees.
@calebdw
calebdw force-pushed the calebdw/push-szrsklqtlxzq branch from e8cd42f to daa9270 Compare August 14, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants